﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Configuration;

namespace Hxsoft.AppV1
{
	public class Page : System.Web.UI.Page
	{
		private Dictionary<string, IncludeFileType> _headIncludeFiles;
		private List<string> _ignoreHeadIncludeFiles;
		private List<PageMessage> _messages;

		protected Dictionary<string, IncludeFileType> HeadIncludeFiles
		{
			get
			{
				if (_headIncludeFiles == null) _headIncludeFiles = new Dictionary<string, IncludeFileType>();
				return _headIncludeFiles;
			}
		}

		public List<string> IgnoreHeadIncludeFiles
		{
			get
			{
				if (_ignoreHeadIncludeFiles == null) _ignoreHeadIncludeFiles = new List<string>();
				return _ignoreHeadIncludeFiles;
			}
		}
		
		private bool _isRewriterAjaxPostUrl = false;
		protected virtual bool IsRewriterAjaxPostUrl
		{
			get { return _isRewriterAjaxPostUrl; }
			set { _isRewriterAjaxPostUrl = value; }
		}

		#region headScript
		private Dictionary<string, string> _headScripts;
		public void RegisterHeadScript(string key, string script)
		{
			if (_headScripts == null)
				_headScripts = new Dictionary<string, string>();
			if (!_headScripts.ContainsKey(key))
				_headScripts[key] = script;
		}

		public void UnregisterHeadScript(string key)
		{
			if (_headScripts == null)
				return;
			if (_headScripts.ContainsKey(key))
				_headScripts.Remove(key);

		}
		#endregion

		#region Metas
		private static readonly string DefaultMetaKeywords = ConfigurationManager.AppSettings["MetaKeywords"];
		private static readonly string DefaultMetaDescription = ConfigurationManager.AppSettings["MetaDescription"];
		private static readonly string DefaultMetaAuthor = ConfigurationManager.AppSettings["MetaAuthor"];
		private static readonly string DefaultMetaCopyright = ConfigurationManager.AppSettings["MetaCopyright"];
		public static readonly string TitleSuffix = ConfigurationManager.AppSettings["PageTitleSuffix"];
		public static readonly string WebsiteName = ConfigurationManager.AppSettings["WebsiteName"];
		public static readonly string WebsiteMainProductName = ConfigurationManager.AppSettings["WebsiteMainProductName"];
		public static readonly string TitleSiteSeparator = "-";
		public static readonly string TitleSectionSeparator = "_";

		private Dictionary<string, string> _metas;
		public Dictionary<string, string> Metas
		{
			get
			{
				if (_metas == null)
				{
					_metas = new Dictionary<string, string>();

					if(!string.IsNullOrEmpty(DefaultMetaKeywords)) _metas[MetaKeywords] = DefaultMetaKeywords;
					if(!string.IsNullOrEmpty(DefaultMetaDescription)) _metas[MetaDescriptionKey] = DefaultMetaDescription;
					if(!string.IsNullOrEmpty(DefaultMetaAuthor)) _metas[MetaAuthorKey] = DefaultMetaAuthor;
					if(!string.IsNullOrEmpty(DefaultMetaCopyright)) _metas[MetaCopyrightKey] = DefaultMetaCopyright;
				}

				return _metas;
			}
		}

		public const string MetaKeywordsKey = "keywords";
		public virtual string MetaKeywords
		{
			get { return Metas.ContainsKey(MetaKeywordsKey) ? Metas[MetaKeywordsKey] : null; }
			set { Metas[MetaKeywordsKey] = value; }
		}

		public string MetaDescriptionKey = "description";
		public virtual string MetaDescription
		{
			get { return Metas.ContainsKey(MetaDescriptionKey) ? Metas[MetaDescriptionKey] : null; }
			set { Metas[MetaDescriptionKey] = value; }
		}

		public string MetaAuthorKey = "author";
		public virtual string MetaAuthor
		{
			get { return Metas.ContainsKey(MetaAuthorKey) ? Metas[MetaAuthorKey] : null; }
			set { Metas[MetaAuthorKey] = value; }
		}

		public string MetaCopyrightKey = "Copyright";
		public virtual string MetaCopyright
		{
			get { return Metas.ContainsKey(MetaCopyrightKey) ? Metas[MetaCopyrightKey] : null; }
			set { Metas[MetaCopyrightKey] = value; }
		}
		#endregion

		/// <summary>
		/// 注册头部包含文件。
		/// </summary>
		/// <param name="fileUrl">包含文件的Url。</param>
		/// <param name="fileType">包含文件的类别。</param>
		public void RegisterHeadIncludeFile(string fileUrl, IncludeFileType fileType)
		{
			Dictionary<string, IncludeFileType> headIncludeFiles = HeadIncludeFiles;
			if (!headIncludeFiles.ContainsKey(fileUrl))
				headIncludeFiles[fileUrl] = fileType;
		}

		public void RegisterHeadIncludeFile(Dictionary<string, IncludeFileType> files)
		{
			foreach (var file in files)
				RegisterHeadIncludeFile(file.Key, file.Value);
		}

		/// <summary>
		/// 移除头部文件注册。
		/// </summary>
		/// <param name="fileUrl"></param>
		public void UnregisterHeadIncludeFile(string fileUrl)
		{
			Dictionary<string, IncludeFileType> headIncludeFiles = HeadIncludeFiles;
			if (headIncludeFiles.ContainsKey(fileUrl))
				headIncludeFiles.Remove(fileUrl);
		}

		/// <summary>
		/// 页面消息集合。
		/// </summary>
		public List<PageMessage> Messages
		{
			get
			{
				if (_messages == null)
					_messages = new List<PageMessage>();
				return _messages;
			}
		}

		protected string BuildHeadIncludeHtml(string fileUrl, IncludeFileType fileType)
		{
			switch (fileType)
			{
				case IncludeFileType.CSS:
					return @"<link rel=""stylesheet"" type=""text/css"" href=""" + this.ResolveUrl(fileUrl) + @""" />";
				case IncludeFileType.JS:
					return @"<script type=""text/javascript"" src=""" + this.ResolveUrl(fileUrl) + @"""></script>";
			}
			return fileUrl;
		}

		protected override void Render(HtmlTextWriter writer)
		{
			if (this.Header != null)
			{
				foreach (var meta in Metas)
				{
					if (!string.IsNullOrEmpty(meta.Value))
						this.Header.Controls.Add(new LiteralControl(@"<meta name=""" + meta.Key + @""" content=""" + meta.Value + @""" />" + "\n"));
				}
			}

			if (HeadIncludeFiles != null && HeadIncludeFiles.Count > 0)
			{
				foreach (var ignore in IgnoreHeadIncludeFiles)
					UnregisterHeadIncludeFile(ignore);

				if (this.Header != null)
				{
					foreach (KeyValuePair<string, IncludeFileType> item in HeadIncludeFiles)
						this.Header.Controls.Add(new LiteralControl(BuildHeadIncludeHtml(item.Key, item.Value) + "\n"));
				}
				else if (this.Form != null)
				{
					foreach (KeyValuePair<string, IncludeFileType> item in HeadIncludeFiles)
					{
						if (!ClientScript.IsClientScriptBlockRegistered(typeof(Page), item.Key))
							ClientScript.RegisterClientScriptBlock(typeof(Page), item.Key, BuildHeadIncludeHtml(item.Key, item.Value));
					}
				}
				else
				{
					foreach (KeyValuePair<string, IncludeFileType> item in HeadIncludeFiles)
					{
						Response.Write(BuildHeadIncludeHtml(item.Key, item.Value));
					}
				}
			}

			if (_headScripts != null && _headScripts.Count > 0)
			{
				if (this.Header != null)
				{
					foreach (KeyValuePair<string, string> item in _headScripts)
						this.Header.Controls.Add(new LiteralControl(item.Value));
				}
				else if (this.Form != null)
				{
					foreach (KeyValuePair<string, string> item in _headScripts)
					{
						if (!ClientScript.IsClientScriptBlockRegistered(typeof(Page), item.Key))
							ClientScript.RegisterClientScriptBlock(typeof(Page), item.Key, item.Value);
					}
				}
				else
				{
					foreach (KeyValuePair<string, string> item in _headScripts)
					{
						Response.Write(item.Value);
					}
				}
			}

			if (_messages != null)
			{
				System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), PageMessage.ClientMessageKey
					, @"var __messageContainer = document.getElementById(""" + PageMessage.ClientMessageKey + @""");if(__messageContainer) __messageContainer.value = """ + PageMessage.EncodeMessages(_messages) + @""";", true);
			}

			//if (_messages != null)
			//{
			//    string strMessages = PageMessage.EncodeMessages(_messages);
			//    if (!string.IsNullOrEmpty(strMessages))
			//        this.Response.AppendHeader(PageMessage.ClientMessageKey, strMessages.Escape());
			//}

			if (IsRewriterAjaxPostUrl && this.Form != null)
			{
				System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "RewriterAjaxPostUrl", @"document.getElementById(""" + this.Form.ClientID + @""").action="""";", true);
			}

			base.Render(writer);
		}
	}

	public enum IncludeFileType
	{
		CSS,
		JS
	}
}
